package com.zzx.test.thread.juc;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicStampedReference;

/**
 * @ClassName: CASDemo
 * @Description: CAS测试类
 * @Author zhouzhixin
 * @Date 2021/11/11
 * @Version 1.0
 */
public class CASDemo {

    static AtomicStampedReference<Integer> atomicStampedReference = new AtomicStampedReference<>(0, 0);

    public static void main(String[] args) {
        try {
            // 必定成功,原子性操作
            new Thread(() -> {
                for (int i = 0; i < 10000; i++) {
                    increment();
                }
            }).start();
            new Thread(() -> {
                for (int i = 0; i < 10000; i++) {
                    increment();
                }
            }).start();
            TimeUnit.SECONDS.sleep(3);
            System.out.println(atomicStampedReference.getStamp());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }


    /**
     * 自增+1
     */
    public static void increment() {
        // 死循环，直到cas成功
        for (; ; ) {
            // 必须先get出来，不能在compareAndSet里面在get，否则不能保证多个get获取到的是不同值
            Integer i1 = atomicStampedReference.getReference();
            int s1 = atomicStampedReference.getStamp();
            Integer i2 = i1 + 1;
            int s2 = s1 + 1;
            boolean result = atomicStampedReference.compareAndSet(i1, i2, s1, s2);
            // 失败则继续循环
            if (result) {
                return;
            }
        }
    }

}
